﻿using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Content;

namespace PrisonStep
{
    public class Dalek
    {

        #region MemberVariables

        private enum States { Stance, Walkstart, Walkloop, Tantrum, CatchEat, Ob };

        /// <summary>
        /// The animation model for dalek
        /// </summary>
        private AnimatedModel mDalek;

        /// <summary>
        /// Our Game
        /// </summary>
        private PrisonGame mGame;

        /// <summary>
        /// Player location in the prison. Only x/z are important. y still stay zero
        /// unless we add some flying or jumping behavior later on.
        /// </summary>
        private Vector3 location = new Vector3(0, 0, 0);//(275, 0, 1053);

        /// <summary>
        /// The player orientation as a simple angle
        /// </summary>
        private float orientation = 0.0f;

        /// <summary>
        /// The player transformation matrix. Places the player where they need to be.
        /// </summary>
        private Matrix transform = Matrix.Identity;

        /// <summary>
        /// Our initial state
        /// </summary>
        private States mState = States.Stance;

        /// <summary>
        /// Whether or not Dalek's eye will follow the human
        /// </summary>
        private bool mFollowHuman = false;

        private const float mAnimationTime = 1.0f;

        private float mElapsedTime;

        private BoundingCylinder mBoundingCyl = null;

        #endregion

        #region Properties

        public Vector3 Location { get { return location; } set { location = value; } }

        public Matrix DalekHead
        {
            get { SetTransform(); return mDalek.GetBoneTransforms("Head"); }
            set { mDalek.SetBoneTransforms("Head", value); mDalek.ComputeAbsoluteTransforms(); }
        }

        public Matrix DalekEye
        {
            get { SetTransform(); return mDalek.GetBoneTransforms("Eye"); }
            set { mDalek.SetBoneTransforms("Eye", value); mDalek.ComputeAbsoluteTransforms(); }
        }

        public Matrix DalekArm
        {
            get { SetTransform(); return mDalek.GetBoneTransforms("Arm2"); }
            set { mDalek.SetBoneTransforms("Arm2", value); mDalek.ComputeAbsoluteTransforms(); }
        }

        public Matrix DalekPlunger
        {
            get { SetTransform(); return mDalek.GetBoneTransforms("PlungerArm"); }
            set { mDalek.SetBoneTransforms("PlungerArm", value); mDalek.ComputeAbsoluteTransforms(); }
        }

        public BoundingCylinder BoundingCyl { get { ComputeBoundingCylinder();  return mBoundingCyl; } }

        #endregion

        public Dalek(PrisonGame aGame)
        {
            this.mGame = aGame;
            mDalek = new AnimatedModel(aGame, "Dalek");
            mDalek.Skinned = false;

            mBoundingCyl = new BoundingCylinder(location, 135, 52);

            mElapsedTime = 0.0f;
        }
        private void SetTransform()
        {
            transform = Matrix.CreateRotationY(orientation);
            transform.Translation = location;
        }


        public void LoadContent(ContentManager aContent)
        {
            mDalek.LoadContent(aContent);
        }

        /// <summary>
        /// This function is called to update this component
        /// to the current game time
        /// </summary>
        /// <param name="aGameTime"></param>
        public void Update(GameTime aGameTime)
        {
            double lDeltaTotal = aGameTime.ElapsedGameTime.TotalSeconds;

            /*do
            {

                double lDelta = lDeltaTotal;

                Ray lRay = new Ray(mGame.Victoria.BazMat.Translation, mGame.Victoria.BazMat.Backward);

                //State Machine goes here



            }while ( lDeltaTotal > 0);*/


            //Make Dalek's head follow the player
            Vector3 lDalekToPlayer = new Vector3(mGame.Victoria.VictoriaLocation.X - location.X, 0, mGame.Victoria.VictoriaLocation.Z - location.Z);
            DalekHead = Matrix.CreateRotationZ(-(float)Math.Atan2(lDalekToPlayer.Z, lDalekToPlayer.X) - orientation + (float)Math.PI / 2f) *
                        mDalek.GetBindTransforms("Head");

            mDalek.Update(lDeltaTotal);
        }

        /// <summary>
        /// This function is called to draw this game component
        /// </summary>
        /// <param name="aGraphics">Devicet to draw the model on.</param>
        /// <param name="aGameTime">Currentgame time.</param>
        /// <param name="aTransform">Transform that puts the model where we want it.</param>
        public void Draw(GraphicsDeviceManager aGraphics, GameTime aGameTime)
        {
            mDalek.Draw(aGraphics, aGameTime, transform);
        }

        private void MoveArms(float aDelta)
        {
            //Get the current transform matricies for the different arms.

            Matrix lPlungerTransform = mDalek.GetBoneTransforms("PlungerArm");
            Matrix lOtherArm = mDalek.GetBoneTransforms("Arm2");


        }

        private void ComputeBoundingCylinder()
        {
            mBoundingCyl.Location = location;
            
        }
    }
}
